use std::io;
use std::ops::Add;

#[derive(Debug, PartialEq)]
struct Point<T> {
    x: T,
    y: T
}

impl<T> Point<T> {
    fn new(x: T, y: T) -> Self {
        return Point{ x: x, y: y };
    }
}

impl Add for Point<u32> {
    type Output = Self;
    fn add(self, other: Point<u32>) -> Point<u32> {
        Point { x: self.x + other.x, y: self.y + other.y }
    }
}

// use std::string;
// impl Add for std::string {
//     fn Add(std::string, &str) -> String;
// }
    
trait Page {
    fn set_page(p: i32) {
        println!("Page default 10");
        // return p;
    }
}

trait PerPage {
    fn set_perpage(num: i32) {
        println!("Per page default 30");
        // return num;
    }
}

#[derive(PartialEq)]
struct MyPaginate { page: i32 }

impl Page for MyPaginate {
    fn set_page(p: i32) {
        println!("{}", p);
        // return p;
    }
}
impl PerPage for MyPaginate {
    fn set_perpage(num: i32) {
        println!("{}", num / 10);
        // return num / 10;
    }
}

trait Pageinate: Page + PerPage {
    fn set_skip_page(&self, num: i32) {
        println!("Skip page: {}", num);
    }
}
impl <T: Page + PerPage> Pageinate for T {}
fn main() {
    // let mut guess = String::new();
    // io::stdin().read_line(&mut guess).expect("failed!");
    // println!("{}", guess);
    
    // let my_paginate = MyPaginate{ page: 199 };
    // my_paginate.set_page(2);
    // my_paginate.set_perpage(100);
    // println!("{}", my_paginate.page);
    // my_paginate.set_skip_page(12);

    println!("{:?}", Point { x: 2, y:0 } + Point { x: 1, y: 3 });
}

#[cfg(test)]// It tells the Rust compiler that the following code should only be compiled when the test configuration is active
pub mod tests {
    use super::*;
    #[test]
    fn comparison_point() {
        assert_eq!(Point { x: 2, y: 0 } + Point { x: 1, y: 3 }, Point { x: 3, y: 3 });
    }
    fn PageAdd() {
        let res = MyPaginate::set_page(10);
        assert_eq!(res, ());
    }
}
